package 力扣._00周赛._425_周赛.问题3;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Solution {
    class Node {
        int val;
        int max1;
        int max2;
        int k;

        public Node(int val,int k) {
            this.k = k;
            this.val = val;
            this.max1 = getOp1();
            this.max2 = getOp2();

        }
        // op1能减少的最大值 nums[i] 除以 2，并向上取整到最接近的整数
        int getOp1() {
            int newNum = (int)Math.ceil(val / 2.0);
            return val - newNum;
        }
        // op2能减少的最大值,仅当 nums[i] 大于或等于 k 时，从 nums[i] 中减去 k
        int getOp2() {
            if(val >= k)
                return k;
            else
                return 0;
        }
    }
    public int minArraySum(int[] nums, int k, int op1, int op2) {
        // 排序、求和、取最大值的看op1和op2那个减得值更大就用那个
        int sum = 0;
        for (int j : nums) {
            sum += j;
        }
        // 将所有值改成对象，存储op1和op2的剩余操作次数，然后用两个队列存储
        List<Node> op1list = new ArrayList<>();
        for (int num : nums) {
            op1list.add(new Node(num, k));
        }
        List<Node> op2list = new ArrayList<>(op1list);
        // 按照op1和op2的最大值排序
        op1list.sort((a,b) -> b.max1 - a.max1);
        op2list.sort((a,b) -> {
            if(a.max2 == b.max2)
                return a.val - b.val;
            return b.max2 - a.max2;
        });

        while (op1>0 && op2>0) {
            Node op1Node = op1list.get(0);
            Node op2Node = op2list.get(0);

            if(op1Node.max1 >= op2Node.max2) {
                sum -= op1Node.max1;
                op1list.remove(0);
                if(op2list.contains(op1Node)) {
                    op1Node.val = op1Node.val - op1Node.max1;
                    op1Node.max2 = op1Node.getOp2();
                    op2list.sort((a,b) -> {
                        if(a.max2 == b.max2)
                            return a.val - b.val;
                        return b.max2 - a.max2;
                    });
                }
                op1--;
            }
            else {
                sum -= op2Node.max2;
                op2list.remove(0);
                if (op1list.contains(op2Node)){
                    op2Node.val = op2Node.val - op2Node.max2;
                    op2Node.max1 = op2Node.getOp1();
                    op1list.sort((a, b) -> b.max1 - a.max1);
                }
                op2--;
            }
        }
        while (op1>0) {
            Node op1Node = op1list.get(0);
            sum -= op1Node.max1;
            op1list.remove(0);
            op1--;
        }
        while (op2>0) {
            Node op2Node = op2list.get(0);
            sum -= op2Node.max2;
            op2list.remove(0);
            op2--;
        }
        return sum;

    }

    public static void main(String[] args) {
        //[2,0]
        //2
        //1
        //2
        Solution solution = new Solution();
//        int[] nums = {2,0};
//        int k = 2;
//        int op1 = 1;
//        int op2 = 2;
        // [2,4,3]
        //3
        //2
        //1
        int [] nums = {2,4,3};
        int k = 3;
        int op1 = 2;
        int op2 = 1;


        System.out.println(solution.minArraySum(nums, k, op1, op2));

    }
}